MediaLiveのWorkflow Wizardで作成されるリソースをカスタマイズ! ~MediaStoreのCORSとCDN認証の設定を入れてみよう~
はじめに
清水です。先月アップデートされたAWS Elemental MediaLiveのWorkflow Wizard機能、リソースの作成はCloudFormation Stackで行われており、このTemplateを編集することでリソースのカスタマイズが可能です。本エントリではこの一例として、AWS Elemental MediaStoreをライブオリジンとした場合のCORS設定とCDN設定ををカスタマイズで追加してみたのでまとめてみます。
カスタマイズ内容の詳細については、以下エントリなどをあわせてご確認ください。
- AWS Elemental MediaStoreでCORSを設定してみた | DevelopersIO
- CloudFrontではデフォルトでOriginヘッダ自体の転送をしている話〜Video.jsで発生するCORSエラーのトラブルを例にして | DevelopersIO
- AWS Elemental MediaStoreでCDN認証してオリジン保護してみた | DevelopersIO
MediaLiveのWorkflow Wizardで作成されるリソースをカスタマイズしてみる
ベースとなるWorkflowの作成
まずは編集のベースとなるWorkflowをWorkflow Wizardから作成していきます。MediaLiveマネジメントコンソールのWorkflow Wizard、[Create workflow]ボタンから進みます。Step 1 Enter basic detailsではWorkflow名やChannel class(今回はSINGLE_PIPELINEとしました)、IAM roleを設定します。
続いてStep 2 Choose a video sourceでInput typeなどを設定します。今回はRTMP (push)を利用します。
Step 3 Add video outputsではOutput groupsを設定を行います。MediaStore(HLS to MediaStore)を選択しました。MediaStore Containerは新規に作成するとします。Video renditionsはデフォルトのままとしました。
最後のStep 4 Review and create resourcesで内容を確認して、[Create workflow resources]ボタンでリソースを作成します。
Workflowsが作成されるまで、しばらく待ちましょう。
Workflowに対応するCloudFormation Stackの確認
Workflowが作成されるのを待ちながら、このWorkflowに対応するCloudFormation Stackについて確認しておきます。先ほどの画面の上部、「This workflow is deployed as a CloudFormation stack」に続くリンクから、もしくはCloudFormationのマネジメントコンソールでWorkflow名のStackを直接確認することもできます。
ここでTemplateタブを確認すると、このCloudFormation Stackに対応するTemplateが参照できます。JSONでしかも改行がないため見辛いですが、編集のため、コピペしてファイルなどにまとめておきましょう。
Workflowに対応するCloudFormation Templateの編集
それではCloudFormation Templateを編集していきます。(以降、私の試行錯誤の結果でWorkflow名称の末尾に「2」がつくようになっていますが、内容は同じです。適宜読み替えてください。)
先ほどのマネジメントコンソールで確認したJSONファイルを、まずはjqコマンドにとおして整形しました。(pbpaste | jq . > template.json
なぐあいです。)
そのファイルを編集していきます。お好みのエディタで行いましょう。私はCloudFormation (JSON)編集にカスタマイズしているEmacsを使用しました。
編集内容はCORS設定として、MediaStoreのCorsポリシーの変更(追加)とCloudFrontのOriginヘッダ転送を行います。またCDN認証設定として、MediaStoreのコンテナポリシーのUserAgentを具体的に指定、CloudFront側でもOriginCustomHeadersのUser-AgentにMediaStore側コンテナポリシーと同じUserAgentの値を指定します。この値はsesame-ouvre-toi
としました。
これらを編集したファイルの差分は下記となります。
% diff -u customize-workflow2-before.json customize-workflow2-edit.json --- customize-workflow2-before.json 2021-04-30 23:11:03.000000000 +0900 +++ customize-workflow2-edit.json 2021-04-30 23:10:53.000000000 +0900 @@ -28,7 +28,15 @@ "Properties": { "AccessLoggingEnabled": false, "ContainerName": "customize-workflow2", - "Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"MediaStoreFullAccess\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"},\"Resource\":\"arn:aws:mediastore:ap-northeast-1:123456789012:container/customize-workflow2/*\",\"Action\":\"mediastore:*\",\"Condition\":{\"Bool\":{\"aws:SecureTransport\":\"true\"}}},{\"Sid\":\"CloudFrontRead\",\"Effect\":\"Allow\",\"Principal\":\"*\",\"Resource\":\"arn:aws:mediastore:ap-northeast-1:123456789012:container/customize-workflow2/*\",\"Action\":[\"mediastore:GetObject\",\"mediastore:DescribeObject\"],\"Condition\":{\"StringEquals\":{\"aws:UserAgent\":\"\"},\"Bool\":{\"aws:SecureTransport\":\"true\"}}}]}", + "CorsPolicy": [ + { + "AllowedHeaders" : [ "*" ], + "AllowedMethods" : [ "GET", "HEAD" ], + "AllowedOrigins" : [ "*" ], + "MaxAgeSeconds" : 3000 + } + ], + "Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"MediaStoreFullAccess\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123456789012:root\"},\"Resource\":\"arn:aws:mediastore:ap-northeast-1:123456789012:container/customize-workflow2/*\",\"Action\":\"mediastore:*\",\"Condition\":{\"Bool\":{\"aws:SecureTransport\":\"true\"}}},{\"Sid\":\"CloudFrontRead\",\"Effect\":\"Allow\",\"Principal\":\"*\",\"Resource\":\"arn:aws:mediastore:ap-northeast-1:123456789012:container/customize-workflow2/*\",\"Action\":[\"mediastore:GetObject\",\"mediastore:DescribeObject\"],\"Condition\":{\"StringEquals\":{\"aws:UserAgent\":\"sesame-ouvre-toi\"},\"Bool\":{\"aws:SecureTransport\":\"true\"}}}]}", "Tags": [ { "Key": "MSAM-Diagram", @@ -109,7 +117,8 @@ ], "Compress": false, "ForwardedValues": { - "QueryString": false + "QueryString": false, + "Headers": [ "Origin" ] }, "SmoothStreaming": false, "ViewerProtocolPolicy": "redirect-to-https", @@ -152,7 +161,7 @@ "OriginCustomHeaders": [ { "HeaderName": "User-Agent", - "HeaderValue": "" + "HeaderValue": "sesame-ouvre-toi" } ] }
編集したTemplateでUpdate Stack
CloudFormation Templateの編集ができたら、実際にCloudFormation StackをUpdateしてみます。なお、MediaLiveのChannelは停止しており、そもそもいちどもStartさせていない状態で確認をしています。
CloudFormationのマネジメントコンソールから、Update stackで「Replace current template」を選択、テンプレートファイルをアップロードします。
パラメータ、オプションについてはそのまま次に進みます。Review画面では、最後のChange set previewについても確認し、[Update stack]でスタックをUpdateします。
Update Stackが完了しました。リソースの操作としてはMediaStoreコンテナ、ならびにCloudFrontディストリビューションのアップデートとなりました。
実際にカスタマイズした環境を確認
Update Stackが完了したので、実際にカスタマイズした環境を確認してみましょう。まずはCORS設定まわりから、MediaStoreのCORSポリシーが設定されていますね。
CloudFrontディストリビューションでのOriginヘッダ転送も設定されています。
続いてCDN認証です。MediaStoreのコンテナポリシー、UserAgent部分に値が入っています。
CloudFrontのオリジン設定でも、指定したUser-Agentヘッダの値をオリジンに転送するようになっていますね。
設定自体がカスタマイズできていることが確認できました。実際にHTTPリクエストでも確認してみましょう。MediaLiveのChannelをスタートさせ、映像を打ち上げます。MediaStoreにMediaLiveからのファイルが書き込まれたところで、これらのファイルを取得してみます。
CORS設定が行われており、Access-Control-Allow-Origin
ヘッダが付与されていることがわかりますね。またオリジンであるMediaStoreにきちんとリクエストが許可されている(CDNが認証されている)状態です。
% curl -I -H"Origin: https://example.com" https://dXXXXXXXXXXXXX.cloudfront.net/livea/main.m3u8 HTTP/1.1 200 OK Content-Type: application/vnd.apple.mpegurl Content-Length: 641 Connection: keep-alive x-amzn-RequestId: AUTUOFBF6EWYAO6ME4VPAJRRGAG5TEO5HVPFQMTKWWV4XZXFZWFNNXMBKTSJZ6C2YPKSH5NXXXXXXXXXXXXXXXX Last-Modified: Fri, 30 Apr 2021 14:31:39 GMT Access-Control-Allow-Origin: https://example.com Cache-Control: max-age=3 ETag: 85461318f951e177ae130ab54539470a142c4e509d9d5a45XXXXXXXXXXXXXXXX Access-Control-Expose-Headers: Content-Range,X-Forwarded-Proto,Last-Modified,Date,x-amzn-cipher-suite,x-amzn-ErrorMessage,Cache-Control,ETag,x-amzn-RequestId,x-amzn-ErrorType,X-Forwarded-For,Content-Length,Content-Type Access-Control-Allow-Credentials: true Date: Fri, 30 Apr 2021 14:32:53 GMT Vary: Origin X-Cache: Miss from cloudfront Via: 1.1 077f2d4a021fffecXXXXXXXXXXXXXXXX.cloudfront.net (CloudFront) X-Amz-Cf-Pop: NRT20-C1 X-Amz-Cf-Id: Qd3W66pGIfxIWwoJmrAveGuonVr7HVuzQoJ0G3XXXXXXXXXXXXXXXX==
まとめ
AWS Elemental MediaLiveのWorkflow Wizard機能で作成したリソースについて、CloudFormationのTemplateを変更してStackをUpdateすることでカスタマイズを行なってみました。AWS Elemental MediaStoreをライブオリジンに使用するケースで、CORS設定とCDN認証設定は定番のカスタマイズではないでしょうか。改行のない、そして最近ではあまり見かけなくなった(?)JSON形式のCloudFormation Templateをみたときはギョッとしましたが、ライブ動画配信環境をシンプルに作成できるMediaLiveのWorkflow Wizard、環境のカスタマイズも容易に行えますね。非常に強力な機能だなと改めて思いました。